package com.ruibang.glass.iso.service.impl.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.common.constants.Constants;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.common.domain.GlobalUser;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceCreate;
import com.ruibang.glass.common.domain.camunda.BpmProcessInstanceStatus;
import com.ruibang.glass.common.domain.camunda.BpmTaskApproveReq;
import com.ruibang.glass.common.domain.file.FileBusiness;
import com.ruibang.glass.common.domain.file.FileInfo;
import com.ruibang.glass.iso.constant.IsoErrorCode;
import com.ruibang.glass.iso.domain.req.FileManageReq;
import com.ruibang.glass.iso.entity.FileCategory;
import com.ruibang.glass.iso.entity.FileManage;
import com.ruibang.glass.iso.entity.PermissionManage;
import com.ruibang.glass.iso.feign.CamundaApi;
import com.ruibang.glass.iso.feign.FileApi;
import com.ruibang.glass.iso.mapper.FileManageMapper;
import com.ruibang.glass.iso.service.impl.FileCategoryService;
import com.ruibang.glass.iso.service.impl.FileManageService;
import com.ruibang.glass.iso.service.impl.PermissionManageService;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.constant.CommonConstant;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import com.teaming.cloud.framework2.common.model.ResultBody;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: songJinKang
 * @CreateTime: 2024-06-05  15:30
 * @Description: TODO
 * @Version: 1.0
 */
@Slf4j
@Service
public class FileManageServiceImpl extends ServiceImpl<FileManageMapper, FileManage> implements FileManageService {

    @Autowired
    private CommonService commonService;

    @Autowired
    private FileApi fileApi;

    @Autowired
    private RedisSingleService redisService;

    @Autowired
    private PermissionManageService permissionManageService;

    @Autowired
    private FileCategoryService fileCategoryService;

    @Autowired
    private CamundaApi camundaApi;

    private static final String COMPANY_CODE = "SY-";

    @Override
    public IPage<FileManage> pageQuery(FileManageReq fileManageReq) {
        IPage<FileManage> page = baseMapper.pageQuery(new Page<>(fileManageReq.getPageNo(), fileManageReq.getPageSize()), fileManageReq);
        if (page != null && CollectionUtils.isNotEmpty(page.getRecords())) {
            Map<String, BpmProcessInstanceStatus> processMap = null;
            //获取业务流程状态
            ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(
                    page.getRecords().stream().map(fm->fm.getManageId()).collect(Collectors.toList()));
            if (resultBody != null && com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isNotEmpty(resultBody.getData())) {
                processMap = resultBody.getData().stream().collect(Collectors.toMap(bp -> bp.getBusinessKey(), bp -> bp, (bp1, bp2) -> bp1));
            }


            ResultBody<List<FileBusiness>> fileBusinesses =  fileApi.getFileBusinessByIds(page.getRecords().stream().map(fm->fm.getManageId()).collect(Collectors.toList()));
            Map<String,List<String>> fileBusinessMap = null;
            if(fileBusinesses!=null&&fileBusinesses.getData()!=null){
                fileBusinessMap = fileBusinesses.getData().stream().collect(Collectors.toMap(FileBusiness::getBusinessId,FileBusiness::getFileIds,(fb1,fb2)->fb1));
            }

            for (FileManage fileManage : page.getRecords()) {
                Object userNameObj = redisService.hget(RedisKey.USER_GROUP_TYPE, fileManage.getApplyUserId());
                if (userNameObj != null && StringUtils.isNotBlank(userNameObj.toString())) {
                    fileManage.setApplyUserName(userNameObj.toString());
                }
                Object deptNameObj = redisService.hget(RedisKey.DEPT_GROUP_TYPE, fileManage.getDeptId());
                if (deptNameObj != null && StringUtils.isNotBlank(deptNameObj.toString())) {
                    fileManage.setDeptName(deptNameObj.toString());
                }
                if(processMap!=null){
                    BpmProcessInstanceStatus instanceStatus = processMap.get(fileManage.getManageId());
                    if(instanceStatus!=null){
                        fileManage.setProcessId(instanceStatus.getProcessInstanceId());
                    }
                }
                if(fileBusinessMap!=null){
                    List<String> fileIds = fileBusinessMap.get(fileManage.getManageId());
                    if(CollectionUtils.isNotEmpty(fileIds)){
                        fileManage.setAttachmentIds(fileIds);
                        fileManage.setFileNum(fileIds.size());
                    }
                }
            }
        }
        return page;
    }

    @Override
    public void saveInfo(FileManage fileManage) {
        fileManage.setManageId(null);
        fileManage.setApproveStatus(CommonConstant.ZERO_STR);
        GlobalUser user = commonService.getUser();
        if (user == null) {
            throw new ServiceException(IsoErrorCode.GET_CURRENT_USER_FAIL.getCode(), IsoErrorCode.GET_CURRENT_USER_FAIL.getMsg());
        }
        fileManage.setUpdateUserId(user.getUserId());
        fileManage.setUpdateUserName(user.getName());
        fileManage.setIsNewest(CommonConstant.ZERO_STR);

        if(CommonConstant.ONE_STR.equals(fileManage.getOperationType())){
            //检查文件编码是否合格
            checkFileNo(fileManage.getFileNo(),fileManage.getFileCategoryId());
            fileManage.setVersion(CommonConstant.ZERO_INT);
        }else {
            //判断是否存在流程未完成
            Long count = baseMapper.selectCount(Wrappers.<FileManage>lambdaQuery().eq(FileManage::getFileNo,fileManage.getFileNo())
                    .ne(FileManage::getApproveStatus,CommonConstant.TWO_STR));
            if(count>0){
                throw new ServiceException(IsoErrorCode.PROCESS_FILE_NO_IS_EXIST.getCode(), IsoErrorCode.PROCESS_FILE_NO_IS_EXIST.getMsg());
            }

            if(CommonConstant.THREE_STR.equals(fileManage.getOperationType())){
                Integer version = baseMapper.getVersionByNo(fileManage.getFileNo());
                if(version!=null){
                    fileManage.setVersion(version + 1);
                }else{
                    fileManage.setVersion(CommonConstant.ZERO_INT);
                }
            }
        }

        //保存文件
        if(CollectionUtils.isNotEmpty(fileManage.getAttachmentIds())){
            FileBusiness fileBusiness = new FileBusiness();
            fileBusiness.setFileIds(fileManage.getAttachmentIds());
            fileBusiness.setBusinessId(fileManage.getManageId());
            fileApi.updateBusinessById(fileBusiness);
        }

        //保存操作信息
        this.save(fileManage);

        //发起流程
        BpmProcessInstanceCreate bpmProcessInstanceCreate = new BpmProcessInstanceCreate();
        Map<String, Object> variables = new HashMap<>(16);
        variables.put(Constants.PROCESS_INSTANCE_STARTER_USER_ID, fileManage.getApplyUserId());
        variables.put(Constants.PROCESS_INSTANCE_BUSINESS_KEY, fileManage.getManageId());
        variables.put(Constants.PROCESS_INSTANCE_MENU_ID, fileManage.getMenuId());
        bpmProcessInstanceCreate.setVariables(variables);
        bpmProcessInstanceCreate.setBusinessKey(fileManage.getManageId());
        bpmProcessInstanceCreate.setMenuId(fileManage.getMenuId());
        String processId = commonService.startProcess(bpmProcessInstanceCreate);
        //直接通过第一流程节点
        if (StringUtils.isNotBlank(processId)) {
            BpmTaskApproveReq bpmTaskApproveReq = new BpmTaskApproveReq();
            bpmTaskApproveReq.setId(processId);
            bpmTaskApproveReq.setUserId(user.getUserId());
            ResultBody resultBody1 = camundaApi.approve(bpmTaskApproveReq);
            System.out.println(JSON.toJSON(resultBody1));
        }
    }

    /***
     * 检查文件编码是否正确
     * @param fileNo
     */
    private void checkFileNo(String fileNo,String fileCategoryId){
        String fileNoFirst = COMPANY_CODE;

        Long count = baseMapper.selectCount(Wrappers.<FileManage>lambdaQuery().eq(FileManage::getFileNo,fileNo));
        if(count>0){
            throw new ServiceException(IsoErrorCode.FILE_NUMBER_IS_EXIST.getCode(),IsoErrorCode.FILE_NUMBER_IS_EXIST.getMsg());
        }

        FileCategory fileCategory = fileCategoryService.getById(fileCategoryId);
        if(fileCategory!=null){
            fileNoFirst = fileNoFirst.concat(fileCategory.getCode());
            if("SC".equals(fileCategory.getCode())){
                if(fileNo.length()!=13){
                    throw new ServiceException(IsoErrorCode.FILE_NUMBER_IS_ERROR.getCode(),IsoErrorCode.FILE_NUMBER_IS_ERROR.getMsg());
                }else{
                    if(!fileNoFirst.equals(fileNo.substring(0,5))){
                        throw new ServiceException(IsoErrorCode.FILE_NUMBER_IS_ERROR.getCode(),IsoErrorCode.FILE_NUMBER_IS_ERROR.getMsg());
                    }
                }
            }else if ("CX".equals(fileCategory.getCode())){
                if(fileNo.length()!=9){
                    throw new ServiceException(IsoErrorCode.FILE_NUMBER_IS_ERROR.getCode(),IsoErrorCode.FILE_NUMBER_IS_ERROR.getMsg());
                }else{
                    if(!fileNoFirst.equals(fileNo.substring(0,5))){
                        throw new ServiceException(IsoErrorCode.FILE_NUMBER_IS_ERROR.getCode(),IsoErrorCode.FILE_NUMBER_IS_ERROR.getMsg());
                    }
                }
            }else{
                int categoryLen = fileCategory.getCode().length();
                int total = categoryLen + 12;
                if(fileNo.length()!=total){
                    throw new ServiceException(IsoErrorCode.FILE_NUMBER_IS_ERROR.getCode(),IsoErrorCode.FILE_NUMBER_IS_ERROR.getMsg());
                }else{
                    if(!fileNoFirst.equals(fileNo.substring(0,3+categoryLen))){
                        throw new ServiceException(IsoErrorCode.FILE_NUMBER_IS_ERROR.getCode(),IsoErrorCode.FILE_NUMBER_IS_ERROR.getMsg());
                    }
                }
            }
        }
    }

    @Override
    public void processNotice(String businessId) {
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(Collections.singletonList(businessId));
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            //流程实例信息
            BpmProcessInstanceStatus process = resultBody.getData().get(0);
            //判断是否是最后一个节点
            if (process.getNodeKey().equals(Constants.FINISH_NODE_KEY)) {
                //获取业务数据
                FileManage fileManage = this.getById(businessId);
                if(fileManage!=null){
                    baseMapper.updateNewestByFileNo(fileManage.getFileNo());
                    fileManage.setIsNewest(CommonConstant.ONE_STR);
                    fileManage.setReleaseDate(LocalDate.now());
                    this.updateById(fileManage);
                }
            }
        }
    }

    @Override
    public FileManage getDetail(String manageId) {
        FileManage fileManage = baseMapper.selectById(manageId);
        if(fileManage!=null){
            ResultBody<List<String>> resultBody = fileApi.getFileIdsByBusinessId(fileManage.getManageId());
            if(resultBody!=null&&CollectionUtils.isNotEmpty(resultBody.getData())){
                fileManage.setAttachmentIds(resultBody.getData());
            }
        }
        return fileManage;
    }

    /**
     * @Description: 废止
     * @version v1.0
     * @author songJinKang
     * @date 2024-06-17 20:47
     */
    @Override
    public void abolish(FileManage fileManage) {
        if(StringUtils.isEmpty(fileManage.getAbolishId())){
            FileManage oldFileManage = this.getById(fileManage.getManageId());
            if(oldFileManage!=null&&StringUtils.isNotBlank(oldFileManage.getAbolishId())){
                throw new ServiceException(IsoErrorCode.PROCESS_FILE_NO_IS_EXIST.getCode(), IsoErrorCode.PROCESS_FILE_NO_IS_EXIST.getMsg());
            }
            fileManage.setAbolishId(IdWorker.get32UUID());
            BpmProcessInstanceCreate bpmProcessInstanceCreate = new BpmProcessInstanceCreate();
            Map<String, Object> variables = new HashMap<>(16);
            variables.put(Constants.PROCESS_INSTANCE_STARTER_USER_ID, fileManage.getApplyUserId());
            variables.put(Constants.PROCESS_INSTANCE_BUSINESS_KEY, fileManage.getAbolishId());
            variables.put(Constants.PROCESS_INSTANCE_MENU_ID, fileManage.getMenuId());
            bpmProcessInstanceCreate.setVariables(variables);
            bpmProcessInstanceCreate.setBusinessKey(fileManage.getAbolishId());
            bpmProcessInstanceCreate.setMenuId(fileManage.getMenuId());
            String processId = commonService.startProcess(bpmProcessInstanceCreate);
            //直接通过第一流程节点
            if (StringUtils.isNotBlank(processId)) {
                BpmTaskApproveReq bpmTaskApproveReq = new BpmTaskApproveReq();
                bpmTaskApproveReq.setId(processId);
                bpmTaskApproveReq.setUserId(commonService.getUser().getUserId());
                ResultBody resultBody = camundaApi.approve(bpmTaskApproveReq);
                System.out.println(JSON.toJSON(resultBody));
            }
        }

        this.update(Wrappers.<FileManage>lambdaUpdate()
                .set(FileManage::getReason,fileManage.getReason())
                .set(FileManage::getAbolishId,fileManage.getAbolishId())
                .set(FileManage::getReviseContent,fileManage.getReviseContent())
                .eq(FileManage::getManageId,fileManage.getManageId()));
    }

    /**
     * @Description: 更新
     * @version v1.0
     * @author songJinKang
     * @date 2024-06-17 20:47
     */
    public void edit(FileManage fileManage) {
        if(StringUtils.isNotBlank(fileManage.getFileId())){
            ResultBody<FileInfo> resultBody = fileApi.getFileInfo(fileManage.getFileId());
            if(resultBody!=null&&resultBody.getData()!=null){
                FileInfo fileInfo = resultBody.getData();
                if(!fileManage.getFileName().equals(fileInfo.getFileName())){
                    throw new ServiceException(IsoErrorCode.FILE_NAME_IS_DIFFERENCE.getCode(), IsoErrorCode.FILE_NAME_IS_DIFFERENCE.getMsg());
                }
            }
        }

        GlobalUser user = commonService.getUser();
        if (user == null) {
            throw new ServiceException(IsoErrorCode.GET_CURRENT_USER_FAIL.getCode(), IsoErrorCode.GET_CURRENT_USER_FAIL.getMsg());
        }
        fileManage.setUpdateUserId(user.getUserId());
        fileManage.setUpdateUserName(user.getName());
        //保存文件
        FileBusiness fileBusiness = new FileBusiness();
        fileBusiness.setFileIds(fileManage.getAttachmentIds());
        fileBusiness.setBusinessId(fileManage.getManageId());
        fileApi.updateBusinessById(fileBusiness);
        this.updateById(fileManage);
    }


    /***
     * 废止通知
     * @param businessId
     */
    @Override
    public void abolishProcessNotice(String businessId) {
        ResultBody<List<BpmProcessInstanceStatus>> resultBody = camundaApi.queryProcessInstanceStatus(Collections.singletonList(businessId));
        if (resultBody != null && CollectionUtils.isNotEmpty(resultBody.getData())) {
            //流程实例信息
            BpmProcessInstanceStatus process = resultBody.getData().get(0);
            //判断是否是最后一个节点
            if (process.getNodeKey().equals(Constants.FINISH_NODE_KEY)) {
                //获取业务数据
                FileManage fileManage = this.getOne(Wrappers.<FileManage>lambdaQuery().eq(FileManage::getAbolishId,businessId));
                if(fileManage!=null){
                    //下发通知相关部门和人员，取下发人员和下发部门通知
                    this.update(Wrappers.<FileManage>lambdaUpdate().set(FileManage::getIsAbolished,CommonConstant.ONE_STR)
                            .eq(FileManage::getFileNo,fileManage.getFileNo()));
                }
            }
        }
    }

    @Override
    public Object getDetailByAbolishId(String abolishId) {
        FileManage fileManage = baseMapper.selectOne(Wrappers.<FileManage>lambdaQuery().eq(FileManage::getAbolishId,abolishId));
        if(fileManage!=null){
            ResultBody<List<String>> resultBody = fileApi.getFileIdsByBusinessId(fileManage.getManageId());
            if(resultBody!=null&&CollectionUtils.isNotEmpty(resultBody.getData())){
                fileManage.setAttachmentIds(resultBody.getData());
            }
        }
        return fileManage;
    }

    /**
     * @Description: 修订
     * @version v1.0
     * @author songJinKang
     * @date 2024-06-17 20:47
     */
    public void revise(FileManage fileManage) {

    }

    /**
     * @Description: 新增
     * @version v1.0
     * @author songJinKang
     * @date 2024-06-17 20:48
     */
    private void insert(FileManage fileManage) {
        //权限开通
        List<PermissionManage> perData = new ArrayList<>();
        List<String> distributeDeptId = fileManage.getDistributeDeptId();
        List<String> distributeUserId = fileManage.getDistributeUserId();
        if (CollectionUtils.isNotEmpty(distributeDeptId)) {
            //部门
            for (String deptId : distributeDeptId) {
                PermissionManage permissionManage = new PermissionManage();
                permissionManage.setManageId(fileManage.getManageId());
                permissionManage.setObjType(Constants.ONE_STR);
                permissionManage.setObjId(deptId);
                permissionManage.setStatus(Constants.ONE_STR);
                permissionManage.setCheckEndDate(LocalDate.now().plusYears(100));
                permissionManage.setType(Constants.ONE_STR);
                permissionManage.setPerCheck(Constants.ONE_STR);
                permissionManage.setPerEdit(Constants.ZERO_STR);
                permissionManage.setPerDown(Constants.ZERO_STR);
                perData.add(permissionManage);
            }
        }
        if (CollectionUtils.isNotEmpty(distributeUserId)) {
            //用户
            for (String userId : distributeUserId) {
                PermissionManage permissionManage = new PermissionManage();
                permissionManage.setManageId(fileManage.getManageId());
                permissionManage.setObjType(Constants.TWO_STR);
                permissionManage.setObjId(userId);
                permissionManage.setStatus(Constants.ONE_STR);
                permissionManage.setCheckEndDate(LocalDate.now().plusYears(100));
                permissionManage.setType(Constants.ONE_STR);
                permissionManage.setPerCheck(Constants.ONE_STR);
                permissionManage.setPerEdit(Constants.ZERO_STR);
                permissionManage.setPerDown(Constants.ZERO_STR);
                perData.add(permissionManage);
            }
        }
        if (CollectionUtils.isNotEmpty(perData)) {
            permissionManageService.saveBatch(perData);
        }
    }

}
